package java_thinking.unit_18_IO._18_10;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileLock;
import java.util.concurrent.TimeUnit;

/**
 * @Desc:   文件枷锁
 *          1.通过FileChannel调用tryLock()或lock(),就可以获得整个文件的FileLock；
 *          2.SocketChannel、DatagramChannel和ServerSocketChannel不需要加锁。因为它们是从单进程实体继承而来的。
 *            我们通常不在两个进程之间共享网络socket
 *          3.tryLok() 是非阻塞式的，它设法获取锁，但是如果不能获得(其它进程已经持有相同锁，并且不共享时),它将直接从方法
 *            调用返回。
 *          4.lock()是阻塞式的，它要阻塞进程直至锁可以获得，或调用 lock()的线程中断，或调用lock()的通道关闭，使用
 *            FileLock.release()可以释放锁
 *          5.对独占锁/共享锁的支持必须由底层的操作系统提供，如果操作系统不支持共享锁并为每个请求都创建一个锁，那么它就会使用
 *            独占锁，锁的类型(共享或者独占)可以通过 FileLock.isShare() 进行查询
 * @author: cww
 * @DateTime: 2019-05-18 14:26
 */

public class FileLocking {
    private static String file1 = "src/maindemo/java/java_thinking/unit_18_IO/_18_10/FileLocking.txt";
    public static void main(String[] args) throws IOException, InterruptedException {
        FileOutputStream fos = new FileOutputStream(file1);
        FileLock fl = fos.getChannel().tryLock();
        if (fl != null) {
            System.out.println("Locked File");
            TimeUnit.MICROSECONDS.sleep(1000);
            System.out.println("Released Lock");
        }
        fos.close();
        fl.close();

        fos = new FileOutputStream(file1);
        //对文件的一部分上锁，加锁区域由position-size决定，第三个参数决定是否共享锁
        fl = fos.getChannel().lock(10, 1000, true);
    }
}
